package com.byd.sealmanage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.byd.sealmanage.config.CommonMapper;
import com.byd.sealmanage.config.CommonResultOutput;
import com.byd.sealmanage.dao.mybatis.*;
import com.byd.sealmanage.modal.bo.LayuiMenu;
import com.byd.sealmanage.modal.po.TbRole;
import com.byd.sealmanage.modal.po.TbToken;
import com.byd.sealmanage.modal.po.TbUploadTemplate;
import com.byd.sealmanage.modal.po.TbUser;
import com.byd.sealmanage.service.LoginService;
import com.byd.sealmanage.util.GlobalContants;
import com.byd.sealmanage.util.JsonUtil;
import com.byd.sealmanage.util.Md5Tool;
import com.byd.sealmanage.util.UUIDGenerator;
import jdk.nashorn.internal.parser.Token;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.IconMultiStateFormatting;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private TbRoleMapper tbRoleMapper;

    @Autowired
    private TbMenuMapper tbMenuMapper;

    @Autowired
    private TbTokenMapper tbTokenMapper;

    @Autowired
    private TbUploadTemplateMapper tbUploadTemplateMapper;

    /**
     * 获取当前登录用户信息
     * @param jobNumber
     * @return
     */
    @Override
    public TbUser getUserByJobNumber(String jobNumber) {
        TbUser user = tbUserMapper.getUserByJobNumber(jobNumber,null);
        HashSet<TbRole> roles = (HashSet<TbRole>) tbRoleMapper.getUserRoles(jobNumber);
        Iterator<TbRole> iterator = roles.iterator();
        while (iterator.hasNext()){
            TbRole role = iterator.next();
            Set<LayuiMenu> menus = tbMenuMapper.getPermitByRoleId(role.getRoleId(), "menus");
            for(LayuiMenu item : menus){
                Map<String,String> metaInfo = new HashMap<>();
                metaInfo.put("title",item.getTitle());
                metaInfo.put("icon",item.getIcon());
                if("控制台".equals(item.getTitle())){
                    metaInfo.put("affix","true");
                }else{
                    metaInfo.put("type",item.getType());
                }
                item.setMeta(metaInfo);
            }
            role.setMenus(menus);
            role.setButton(tbMenuMapper.getPermitByRoleId(role.getRoleId(),"button"));
        }
        user.setRoles(roles);
        return user;
    }

    /**
     * 登录页面的账号密码验证
     * @param userName
     * @param password
     * @return
     */
    @Override
    public JSONObject checkLoginInfo(String userName, String password) {
        CommonResultOutput commonResultOutput;
        JSONObject jsonObject = new JSONObject();
        try{
            Example example = new Example(TbUser.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("jobnumber", userName);
            criteria.andEqualTo("status", GlobalContants.INT_1);
            TbUser tbUser = tbUserMapper.selectOneByExample(example);
            if(tbUser == null){
                jsonObject.put(GlobalContants.MSG,"账号不存在或者已失效");
                commonResultOutput = new CommonResultOutput("9999",jsonObject);
                return JsonUtil.toJSONObject(commonResultOutput);
            }
            if(!password.equals(tbUser.getPassword())){
                jsonObject.put(GlobalContants.MSG,"密码错误");
                commonResultOutput = new CommonResultOutput("9999",jsonObject);
                return JsonUtil.toJSONObject(commonResultOutput);
            }else{
                TbRole userOneRole = tbRoleMapper.getUserOneRole(userName);
                tbUser.setSalt(userOneRole.getRoleId());
                jsonObject.put("userInfo",tbUser);
            }
            String confirmToken = createToken(userName,"web");
            jsonObject.put("token",confirmToken);
            commonResultOutput =new CommonResultOutput("0000",jsonObject);
        }catch (Exception e){
            e.toString();
            jsonObject.put(GlobalContants.MSG,"登录异常");
            commonResultOutput = new CommonResultOutput("9999",jsonObject);
        }
        return JsonUtil.toJSONObject(commonResultOutput);
    }

    /**
     * 生成token
     * @param userId
     * @return
     */
    @Override
    public String createToken(String userId,String comeType){
        //生成一个token
        String token = UUIDGenerator.getUUID();
        //当前时间
        Date now = new Date();
        //过期时间
        Date expireTime = new Date(now.getTime() + 1000*60*60*2);
        //判断是否生成过token
        Example example = new Example(TbToken.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("comeType",comeType);
        TbToken tokenEntity = tbTokenMapper.selectOneByExample(example);
        if (tokenEntity == null) {
            tokenEntity = new TbToken();
            tokenEntity.setUserId(userId);
            tokenEntity.setToken(token);
            tokenEntity.setUpdateTime(now);
            tokenEntity.setExpireTime(expireTime);
            tokenEntity.setComeType(comeType);
            //保存token
            tbTokenMapper.insertSelective(tokenEntity);
        } else {
            tokenEntity.setToken(token);
            tokenEntity.setUpdateTime(now);
            tokenEntity.setExpireTime(expireTime);
            //更新token
            tbTokenMapper.updateByPrimaryKey(tokenEntity);
        }
        return token;
    }

    /**
     * 查询token
     * @param token
     * @return
     */
    @Override
    public TbToken selectByToken(String token) {
        Example example = new Example(TbToken.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("token",token);
        TbToken tbToken = tbTokenMapper.selectOneByExample(example);
        return tbToken;
    }

    /**
     * 查询角色对应的菜单集合
     * @param roles
     * @return
     */
    @Override
    public Map<String, Object> getMenus(Set<TbRole> roles) {
        Map<String, Object> menuMap = new HashMap<>();
        Iterator<TbRole> iterator = roles.iterator();
        Set<LayuiMenu> menus = new HashSet();
        while(iterator.hasNext()){
            TbRole role = iterator.next();
            menus.addAll(role.getMenus());
        }
        List<LayuiMenu> menusList = new ArrayList<>(menus);
        Collections.sort(menusList, new Comparator<LayuiMenu>() {
            @Override
            public int compare(LayuiMenu o1, LayuiMenu o2) {
                if(Integer.valueOf(o1.getKeyId()) > Integer.valueOf(o2.getKeyId()))
                    return 1;
                else if(Integer.valueOf(o1.getKeyId()) < Integer.valueOf(o2.getKeyId()))
                    return -1;
                else
                    return 0;
            }
        });
        //将查出的菜单进行重组，分为一级菜单、二级菜单和三级菜单
        List<LayuiMenu> oneMenus = new ArrayList<>();
        //先找一级菜单
        for(int i =0;i < menusList.size();i++){
            LayuiMenu menu = menusList.get(i);
            //一级菜单没有父级节点
            if ((menu.getParentId() == null || "".equals(menu.getParentId()))){
                oneMenus.add(menu);
            }
        }
        //查找二级菜单
        /**
         * 利用递归方法查找所有子菜单
         */
        for (LayuiMenu menu : oneMenus) {
            //如果还有子级菜单，诸如三级菜单或四级菜单运用递归找出
            menu.setChildren(getChild(menu.getKeyId(), menusList));
        }
        //将菜单分组的最终结果以LayuiMini指定的形式传给前端
        menuMap.put("code",200);
        Map<String, Object> data = new HashMap<>();
        data.put("menu",oneMenus);
        menuMap.put("data",data);
        return menuMap;
    }

    /**
     * 下载文件
     * @param fileId
     * @return
     */
    @Override
    public ResponseEntity<byte[]> downloadFile(String fileId, HttpServletRequest request) throws IOException {
        Date sysDate = new Date(System.currentTimeMillis());
        Timestamp date = new Timestamp(sysDate.getTime());
        TbUploadTemplate tbUploadTemplate = tbUploadTemplateMapper.selectByPrimaryKey(fileId);
        String uuid = UUIDGenerator.getUUID()+"";
        File downloadFile = new File(tbUploadTemplate.getFileAddress());
        String downloadFilenName = date + uuid + downloadFile.getName().substring(downloadFile.getName().lastIndexOf("."));

        HttpHeaders headers = new HttpHeaders();
        //下载显示的文件名，并解决中文名称乱码问题
        String downloadFileName = new String(downloadFilenName.getBytes("UTF-8"),"iso-8859-1");
        //通知浏览器以attachment（下载方式）打开
        headers.setContentDispositionFormData("attachment", downloadFileName);
        //applicatin/octet-stream: 二进制流数据（最常见的文件下载）
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        // 使用下org.apache.commons.io.FileUtils工具类
        byte[] bytes = FileUtils.readFileToByteArray(downloadFile);
        request.getSession().removeAttribute("fileAddress");
        return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.CREATED);
    }

    /**
     * 获取地区下拉框选项
     * @return
     */
    @Override
    public JSONObject getPlaceOptionService() {
        List<String> placeOptions = new ArrayList<>(GlobalContants.placeList);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("placeOptions",placeOptions);
        CommonResultOutput commonResultOutput = new CommonResultOutput("0000",placeOptions);
        return JsonUtil.toJSONObject(commonResultOutput);
    }

    /**
     * 查找子菜单
     * @param menuId
     * @param rootMenu
     * @return
     */
    private List<LayuiMenu> getChild(String menuId, List<LayuiMenu> rootMenu) {
        // 子菜单
        List<LayuiMenu> childList = new ArrayList<LayuiMenu>();
        for (LayuiMenu menu : rootMenu) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (!(menu.getParentId() == null)) {
                if (menu.getParentId().equals(menuId)) {
                    childList.add(menu);
                }
            }
        }
        //把子菜单的子菜单再循环一遍
        for(LayuiMenu menu : childList){
            if(menu.getComponent() == null || "".equals(menu.getComponent())){
                //递归
                menu.setChildren(getChild(menu.getKeyId(),rootMenu));
            }
        }
        if(childList.size() == 0){
            return null;
        }
        return childList;
    }
}
